/*
 * 程序名：demo02.cpp，此程序用于演示socket通讯的服务端。
 */
#include "../_public.h"

int main(int argc, char *argv[])
{
	if (argc != 2)
	{
		printf("Using:./demo02 port\nExample:./demo02 5005\n\n");
		return -1;
	}

	// 第1步：创建服务端的socket。
	int listenfd;
	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		perror("socket");
		return -1;
	}

	// 第2步：把服务端用于通讯的地址和端口绑定到socket上。
	struct sockaddr_in servaddr; // 服务端地址信息的数据结构。
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;				  // 协议族，在socket编程中只能是AF_INET，代表IPv4
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 任意ip地址
	servaddr.sin_port = htons(atoi(argv[1]));	  // 指定通讯端口
	if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
	{
		perror("bind");
		close(listenfd);
		return -1;
	}

	// 第3步：把socket设置为监听模式。
	if (listen(listenfd, 5) != 0)
	{
		perror("listen");
		close(listenfd);
		return -1;
	}

	// 第4步：接受客户端的连接。
	int clientfd;							  // 客户端的socket。
	int socklen = sizeof(struct sockaddr_in); // struct sockaddr_in的大小
	struct sockaddr_in clientaddr;			  // 客户端的地址信息。
	clientfd = accept(listenfd, (struct sockaddr *)&clientaddr, (socklen_t *)&socklen);
	printf("客户端（%s）已连接。\n", inet_ntoa(clientaddr.sin_addr));

	int iret;
	char buffer[102400];

	// 第5步：与客户端通讯，接收客户端发过来的报文后，回复ok。
	while (1)
	{
		memset(buffer, 0, sizeof(buffer));
		int ibuflen = 0;
		if (TcpRead(clientfd, buffer, &ibuflen) == false) // 接收客户端的请求报文。
		{
			printf("iret=%d\n", iret);
			break;
		}
		printf("接收：%s\n", buffer);

		// exit(0);

		// strcpy(buffer, "ok");
		// if ((iret = send(clientfd, buffer, strlen(buffer), 0)) <= 0) // 向客户端发送响应结果。
		// {
		// 	perror("send");
		// 	break;
		// }
		// printf("发送：%s\n", buffer);
	}

	// 第6步：关闭socket，释放资源。
	close(listenfd);
	close(clientfd);
}
